# Entertainer Frontend - This is a client side of the Entertainer media center.
# Copyright (C) 2007 Lauri Taimila
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"
__version__= "0.1"

import os
import sys
import logging, logging.handlers

from utils.theme import Theme
from utils.configuration import Configuration
from frontend.backend_connection import BackendConnection

# Media libraries
from frontend.medialibrary.feeds import FeedLibrary
from frontend.medialibrary.music import MusicLibrary
from frontend.medialibrary.images import ImageLibrary
from frontend.medialibrary.videos import VideoLibrary

# GUI
import gtk
import clutter
import gobject
from frontend.gui.user_interface import UserInterface

class FrontendClient:
    """
    Entertainer frontend
    
    This is a frontend application of the Entertainer. Frontend is a GUI part
    that user sees on the screen. This class is a core of the frontend. Frontend
    connects to the backend's messagebus at startup.
    """
    
    def __init__(self):
        """
        Create a new frontend. 
        
        This initializes all frontend stuff like media librarys, remote
        control receiver and GUI. After this we just wait user actions.
        """
        
        #Check that installed clutter version is series 0.5 or higher
        if int(clutter.__version__[2]) < 5:
            print """It seems that your Clutter version is too old. Entertainer
                     requires Clutter 0.5 or later. Execution Aborted!"""
            sys.exit(1)
            
        self.configuration = None         # Configuration object
        self.theme = None                 # Theme
        self.logger = None                # Logger object
        self.backend_connection = None    # Connection to the backend server
        self.feed_library = None          # Feed library
        self.music_library = None         # Music library
        self.image_library = None         # Image library
        self.video_library = None         # Video library
        self.ui = None                    # User interface of the frontend
        
        # Initialize clutter threading system.
        #gtk.gdk.threads_init()
        gobject.threads_init() 
        clutter.threads_init()
        #clutter.init()
        
        self.initialize_configuration()
        self.initialize_theme()
        self.initialize_logging()
        self.initialize_backend_connection()
        self.initialize_media_library()
        self.initialize_gui()
        self.ui.start_up(self.configuration.start_in_fullscreen())
        clutter.main()
        #gtk.main()
            
    def initialize_media_library(self):
        """Initialize media library"""
        self.feed_library = FeedLibrary(self.backend_connection)
        self.music_library = MusicLibrary(self.backend_connection)
        self.image_library = ImageLibrary(self.backend_connection)
        self.video_library = VideoLibrary(self.backend_connection)

    def initialize_configuration(self):
        """Initialize configuration"""
        try:
            self.configuration = Configuration()
        except:
            print "Couldn't read configuration file! Execution aborted..."
            sys.exit(1)
            
    def initialize_theme(self):
        """Initialize theme"""
        try:
            self.theme = Theme(self.configuration.get_theme_path())
        except:
            print "Couldn't initialize theme! Execution aborted..."
            sys.exit(1)
        
    def initialize_logging(self):
        """Initializes logging system to use rotating log file."""              
        logfile = os.path.expanduser('~/.entertainer/frontend.log')
        log_format = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
        file_handler = logging.handlers.RotatingFileHandler(logfile, 'r+', 128000, 2)
        file_handler.setFormatter(log_format)
        self.logger = logging.getLogger('') 
        self.logger.setLevel(logging.DEBUG)
        self.logger.addHandler(file_handler)
        self.logger.debug("Logging system intialized successfully")

    def initialize_backend_connection(self):
        """Connect to the backend server."""
        try:
            self.backend_connection = BackendConnection()
            self.logger.debug("Connected to the Entertainer backend server.")
        except:
            print "Couldn't connect to the backend server. Execution aborted!"
            print "Make sure that Entertainer backend server is up and running."
            #TODO: Display GTK-warning dialog? Start backend? What should we do
            sys.exit(1)

    def initialize_gui(self):
        """
        Initialize frontend GUI. 
        
        Create a gui and dislpay it on the screen.
        """
        self.ui = UserInterface(self)
        
    def quit_frontend(self):
        """
        Quit Frontend
        
        This is called when user closes frontend. Before closing application
        the backend connection etc. are closed in a clean way."""
        self.backend_connection.close_connection()
        #gtk.main_quit()
        clutter.main_quit()
        sys.exit(0)
        
    def getTheme(self):
        """
        Get frontend's theme
        @return Theme object - Currently used theme
        """
        return self.theme
        
    def get_logger(self):
        """
        Get logger Frontend logger object.
        @return logger object
        """
        return self.logger
        
    def get_configuration(self):
        """
        Get configuration
        @return Configuration object
        """
        return self.configuration
        
    def get_backend_connection(self):
        """
        Get Backend connection
        @return BackendConnection - active connection to the Entertainer backend
        """
        return self.backend_connection
    
    def getUserInterface(self):
        """
        Get interface object.
        @return UserInterface object
        """
        return self.ui
        
    def get_feed_library(self):
        """Get feed library"""
        return self.feed_library
        
    def get_image_library(self):
        """Get image library"""
        return self.image_library
        
    def get_music_library(self):
        """Get music library"""
        return self.music_library
        
    def get_video_library(self):
        """Get video library"""
        return self.video_library
